#!/usr/bin/env python
# -*- coding:utf-8 -*- 
import csv  # 将数据写入到csv文件中
import random

import pandas as  pd
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

__author__ = 'wangbin'


# 写入文件csv
def write_data(data, name):
    file_name = name
    with open(file_name, 'w', errors='ignore', newline='') as f:
        f_csv = csv.writer(f)
        f_csv.writerows(data)
        f.close()


# 生成测试数据
def outTestDate():
    data = []
    for i in range(1000):
        score1 = random.random() * 100
        score2 = random.random() * 100
        totalScore = score1 + score2
        ispass = 0
        if (totalScore >= 120):
            ispass = 1
        dat = [score1, score2, ispass]

        # print(dat)
        data.append(dat)

    print(data)
    write_data(data, "ex2data1.txt")
    # print(i/7*6)


def readTestData(fileName):
    with open(fileName, 'r', errors='ignore', newline='') as f:
        f_csv = csv.reader(f)
        for line in f_csv:
            print(line[2])
        f.close()


def train():
    # readTestData('ex2data1.txt')
    # 读取数据文件
    df = pd.read_csv("ex2data1.txt", header=None)
    train_data = df.values
    # 分离特征和标签，并获取数据维数
    train_x = train_data[:, :-1]
    train_y = train_data[:, -1:]
    feature_num = len(train_x[0])
    sample_num = len(train_x)

    print("Size of train_x:{}×{}".format(sample_num, feature_num))
    print("Size of train_y:{}×{}".format(len(train_y), len(train_y[0])))

    # 数据集
    # 用TensorFlow定义两个变量用来存放训练用的数据 （placeholder 占位符）
    # x和y意味着这两个变量的值是未指定的，知道开始训练模型时才需要将给定的数据赋值给变量
    x = tf.placeholder(tf.float32)
    y = tf.placeholder(tf.float32)

    # 训练目标
    # W和b意味着这两个变量将在训练迭代的过程中不断变化，最终取得我们期望的值
    # 我们将W的初始值设为了 feature_num 维的0向量 将b初始值设为-0.9（随意舍得，不要介意）
    W = tf.Variable(tf.zeros([feature_num, 1]))
    b = tf.Variable([-0.9])

    # 用TensorFlow的方式将 损失函数 表达出来
    db = tf.matmul(x, tf.reshape(W, [-1, 1])) + b
    hyp = tf.sigmoid(db)

    # 表达损失函数 是分三步进行的:
    # 先分别将就和内的两部分表示出来，再将它们加和并和外面的常数m进行运算
    # 最后对这个向量进行求和，便得到了损失函数的值
    cost0 = y * tf.log(hyp)
    cost1 = (1 - y) * tf.log(1 - hyp)
    cost = (cost0 + cost1) / -sample_num
    loss = tf.reduce_sum(cost)

    # 定义使用的优化方法

    # 第一步是选取优化器（梯度下降方法）
    # 第二步是优化目标使得损失函数的值最小化
    # 注意：此处的学习率（0.001）应当尽可能小，否则可能会出现（损失计算中出现log(0)）的问题
    optimizer = tf.train.GradientDescentOptimizer(0.001)
    train = optimizer.minimize(loss)

    # 训练模型

    # 在TensorFlow中，首先要将之前定义的Variable初始化：
    init = tf.global_variables_initializer()
    # 任务执行主体
    # 我们上面定义了一堆东西，只是一个模型为了得到结果而需要的执行步骤和框架，一个类似流程图的东西
    # 光有流程图还不够，我们需要一个主体来实际的运行它。这就是Session的作用
    sess = tf.Session()
    sess.run(init)

    # gpu 实现
    # 0.333 占用总显存的份额
    # gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
    # sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))

    # 用我们的数据集来对模型进行训练
    feed_dict = {x: train_x, y: train_y}
    for step in range(1000000):
        sess.run(train, feed_dict)
        if (step % 100 == 0):
            print(step, sess.run(W).flatten(), sess.run(b).flatten())


def produceAtlas(w, b):
    # 读取数据文件
    df = pd.read_csv("ex2data1.txt", header=None)
    train_data = df.values
    # 分离特征和标签，并获取数据维数
    x1 = train_data[:, 0]
    x2 = train_data[:, 1]
    y = train_data[:, -1:]

    # 我们先将数据集表示在图表上（x1为横轴，x2为纵轴）
    # 其中，我们用 红色的x 代表 没有被录取 用绿色的o 代表 被录取
    for x1p, x2p, yp in zip(x1, x2, y):
        if yp == 0:
            plt.scatter(x1p, x2p, marker='x', c='r')
        else:
            plt.scatter(x1p, x2p, marker='o', c='g')

    # 其次我们将训练得出的决策边界 xw+b=0 表示到图表上
    # 根据参数得到直线
    # inspace是Matlab中的均分计算指令，用于产生x1,x2之间的N点行线性的矢量
    # 其中x1、x2、N分别为起始值、终止值、元素个数。若默认N，默认点数为100。
    x = np.linspace(20, 100, 10)
    print(x)
    y = []
    for i in x:
        y.append((i * -w[1] - b) / w[0])
    plt.plot(x, y)
    plt.show()


if __name__ == '__main__':
    w = [0.05325482, 0.05214331]
    b = -6.249074
    produceAtlas(w, b)
